﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace Bacon_FTP_Client
{
    /// <summary>
    /// Class that provides FTP file transmision methods.
    /// </summary>
    public class FileTransmisionServices
    {
        #region Properties()

        private string filename { get; set; }
        private string filePath { get; set; }
        private Client server { get; set; }
        private Client client { get; set; }

        public string test = null;

        #endregion

        #region Constructor()

        /// <summary>
        /// FileTransmisionServices constructor.
        /// </summary>
        /// <param name="_filename">Name of the file</param>
        /// <param name="_filePath">Path of the file</param>
        /// <param name="_server">Client server connected</param>
        public FileTransmisionServices(string _filename, string _filePath, Client _server, Client _client)
        {
            filename = _filename;
            filePath = _filePath;
            server = _server;
            client = _client;
        }

        /// <summary>
        /// FileTransmisionServices constructor.
        /// </summary>
        /// <param name="_filename">Name of the file</param>
        /// <param name="_filePath">Path of the file</param>
        /// <param name="_server">Client server connected</param>
        public FileTransmisionServices(Client _server, Client _client)
        {
            server = _server;
            client = _client;
        }

        #endregion

        #region Implementation()

        /// <summary>
        /// Method for sending files throug byte[] array and returns a confirmation.
        /// </summary>
        public void SendFile(object Sender)
        {
            server.GetNetworkStream((IPEndPoint)Sender, server._tcpClient);

            try
            {
                using (FileStream fs = new FileInfo(filePath).OpenRead())
                {
                    byte[] buffer = new Byte[4096];
                    int bytesRead;
                    Stream serverStream = server._tcpClient.GetStream();

                    try
                    {
                        while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) != 0)
                            serverStream.Write(buffer, 0, bytesRead);
                    }
                    catch (Exception exi)
                    {
                        System.Windows.Forms.MessageBox.Show(exi.Message);
                        //throw;
                    }
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
                //throw;
            }

            server._tcpClient.Close();
            ListenForResponse();
        }

        /// <summary>
        /// Method for caching the responses from the server.
        /// </summary>
        /// <returns>The response from the server.</returns>
        private string ListenForResponse()
        {
            try
            {
                ASCIIEncoding encoder = new ASCIIEncoding();
                byte[] message = new byte[1024];
                int bytesRead;

                bytesRead = client._netStream.Read(message, 0, 1024);

                return encoder.GetString(message, 0, bytesRead);
            }
            catch (Exception)
            {
                System.Windows.Forms.MessageBox.Show("Error en el servidor");
                return null;
            }
        }

        /// <summary>
        /// Method for receveing files throug byte[] array and returns a confirmation.
        /// </summary>
        public void ReceiveFile(object Sender)
        {
            server.GetNetworkStream((IPEndPoint)Sender, server._tcpClient);

            try
            {
                using (FileStream fs = new FileStream(filePath/*Directory.GetCurrentDirectory()*/, FileMode.Create))
                {
                    byte[] buffer = new Byte[4096];
                    int bytesRead;
                    Stream serverStream = server._tcpClient.GetStream();

                    try
                    {
                        while ((bytesRead = serverStream.Read(buffer, 0, buffer.Length)) != 0)
                            fs.Write(buffer, 0, bytesRead);
                    }
                    catch (Exception exi)
                    {
                        System.Windows.Forms.MessageBox.Show(exi.Message);
                        //throw;
                    }
                }
            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
                //throw;
            }

            server._tcpClient.Close();
            ListenForResponse();
        }

        /// <summary>
        /// Method for listing the files from the server.
        /// </summary>
        /// <param name="Sender"></param>
        public void ListServer(object Sender)
        {
            server.GetNetworkStream((IPEndPoint)Sender, server._tcpClient);

            try
            {
                byte[] buffer = new Byte[4096];

                int bytesRead;

                Stream serverStream = server._tcpClient.GetStream();

                bytesRead = serverStream.Read(buffer, 0, buffer.Length);

                test = Encoding.ASCII.GetString(buffer, 0, bytesRead);

            }
            catch (Exception ex)
            {
                System.Windows.Forms.MessageBox.Show(ex.Message);
                //throw;
            }

            server._tcpClient.Close();
            ListenForResponse();
        }

        /// <summary>
        /// Method that initialices the LIST thread
        /// </summary>
        /// <param name="serverEndPoint2">Server IpEndPoint</param>
        /// <returns>Returns the response from the server</returns>
        public string InitializeListThread(IPEndPoint serverEndPoint2)
        {
            Thread tred = new Thread(this.ListServer);
            tred.Start(serverEndPoint2);

            //Thread tred = new Thread(new ThreadStart(ListServer()));
            //tred.Start(serverEndPoint2);

            while (tred.IsAlive) { }
            return test;
        }

        #endregion
    }
}
